package restapi

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"log"
	"os"
	"time"
)

// 在restapi包内使用的数据库连接
var ubiScaleViewDB *gorm.DB

// 数据库连接字符串
var dsn string

// gorm日志配置
var dbLogger = logger.New(
	log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer（日志输出的目标，前缀和日志包含的内容——译者注）
	logger.Config{
		SlowThreshold:             time.Second, // 慢 SQL 阈值
		LogLevel:                  logger.Info, // 日志级别
		IgnoreRecordNotFoundError: true,        // 忽略ErrRecordNotFound（记录未找到）错误
		Colorful:                  false,       // 禁用彩色打印
	},
)

// InitializeDB 初始化DB实例
func InitializeDB() {

	logInfo("Initialize UbiScale View DB.")

	if ubiScaleViewDB != nil {
		return
	}

	// 从系统变量获取连接字符串
	dsn = os.Getenv("UBISCALE_VIEW_DB_CONN")

	// 无法获取连接字符串的情况下设置默认值
	if len(dsn) == 0 {
		dsn = "dbo:JobNicer@_2021@tcp(120.79.147.70:3306)/ubiscaleview?charset=utf8mb4&parseTime=True&loc=Local"
	}

	logInfo("Connect UbiScale View DB.")
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: dbLogger})

	if err != nil {
		LogError("Initialize DB error: %v", err.Error())
		os.Exit(1)
	}
	ubiScaleViewDB = db
	logInfo("Connect UbiScale View DB OK.")

	logInfo("Get *sql.DB for connection pool.")
	sqlDB, err := ubiScaleViewDB.DB()

	if err != nil {
		LogError("Initialize DB error: %v", err.Error())
		os.Exit(1)
	}
	logInfo("Get *sql.DB OK.")

	logInfo("Ping DB.")
	err = sqlDB.Ping()

	if err != nil {
		LogError("Initialize DB error: %v", err.Error())
		os.Exit(1)
	}
	logInfo("Ping DB OK.")

	logInfo("Set connection pool.")
	// 设置最大空闲连接
	sqlDB.SetMaxIdleConns(10)
	// 设置最大打开连接数
	sqlDB.SetMaxOpenConns(100)
	// 设置连接可复用的最大时间
	sqlDB.SetConnMaxLifetime(time.Hour)
	logInfo("Set connection pool OK.")
	logInfo("Initialize DB OK.")
}

// calculateOffset 计算翻页处理时的偏移量
func calculateOffset(pageSize, moveTo *int64, total int64) int64 {

	if *moveTo <= 0 {
		*moveTo = 1
	}
	var offset int64
	if *moveTo**pageSize > total {
		remainder := total % *pageSize
		if remainder == 0 {
			offset = total - *pageSize
			*moveTo = total / *pageSize
		} else {
			offset = total - remainder
			*moveTo = offset / *pageSize + 1
		}
	} else {
		offset = (*moveTo - 1) * *pageSize
	}
	return offset
}
